NextJSのWebアプリをAmplify Gen2デプロイしてみた
昨年発表されたAmplify Gen2(プレビュー)ですが、日々機能が少しづつ追加されており、完成度が高まってきました。 前回の記事で作成したNextJS Server ComponentsのWebアプリケーションをHostingし、デプロイまで進めてみました。
Ampify Gen2のHostingの概要
従来のAmplifyでWebアプリケーションをHostingする場合、S3を使ったstatic website hostingと、Amplify Hostingの2つがありましたが、Amplify Gen2では「Amplify Publish」のようなコマンドが無くなり、基本の選択肢からS3ホスティングが外れました。
Amplify Gen2はCustom Resourceという、AmplifyのCDKアプリケーションに既存のCDKコンストラクトを追加する機能があるので、お手軽にAmplify Gen2+S3でHostingしたい時は、NextJSのリソースをStatic Exportし、既存のAmplifyスタックからcreateStackして、Hosting用のCDKを追加すると、Amplifyのデプロイ時に一緒にCDKを実行し、デプロイします。
話が逸れつつありますが、概ねこのようなカスタムリソースで動作します。
import { defineBackend } from "@aws-amplify/backend"; import { auth } from "./auth/resource"; import { data } from "./data/resource"; import * as aws_s3 from "aws-cdk-lib/aws-s3"; import { Distribution, OriginAccessIdentity, } from "aws-cdk-lib/aws-cloudfront"; import { RemovalPolicy } from "aws-cdk-lib"; import { BucketDeployment, Source } from "aws-cdk-lib/aws-s3-deployment"; import { S3Origin } from "aws-cdk-lib/aws-cloudfront-origins"; import { Effect, PolicyStatement, ServicePrincipal } from "aws-cdk-lib/aws-iam"; const backend = defineBackend({ auth, data, }); const contextJson = JSON.parse(process.env.CDK_CONTEXT_JSON ?? "{}"); const stackprefix = contextJson["amplify-backend-type"] === "sandbox" ? contextJson["amplify-backend-name"] : ""; const subStack = backend.createStack(stackprefix + "SubStack"); // Create an S3 bucket for the website const destinationBucket = new aws_s3.Bucket(subStack, "WebsiteBucket", { bucketName: `cdk-hogetest-content-bucket`, blockPublicAccess: aws_s3.BlockPublicAccess.BLOCK_ALL, autoDeleteObjects: true, removalPolicy: RemovalPolicy.DESTROY, }); const originAccessIndetity = new OriginAccessIdentity(subStack, "OAI"); destinationBucket.grantRead(originAccessIndetity); // Create a CloudFront distribution const distribution = new Distribution(subStack, "distro", { defaultBehavior: { origin: new S3Origin(destinationBucket, { originAccessIdentity: originAccessIndetity, }), }, defaultRootObject: "index.html", }); // Deploy the contents of the 'website' directory to the S3 bucket new BucketDeployment(subStack, "DeployWebsite", { sources: [Source.asset("./out")], destinationBucket, distribution, }); // S3 - BucketPolicy const destinationBucketPolicyStatement = new PolicyStatement({ actions: ["s3:GetObject"], effect: Effect.ALLOW, principals: [new ServicePrincipal("cloudfront.amazonaws.com")], resources: [`${destinationBucket.bucketArn}/*`], }); destinationBucket.addToResourcePolicy(destinationBucketPolicyStatement);
/** @type {import('next').NextConfig} */ const nextConfig = { output: "export", }; export default nextConfig;
... "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules/*", "amplify/*", "amplify-backup/*"]. //amplifyフォルダを除外 }
とはいえ、今回はNextJSのServer Componentsを使いたいので、Amplify Hostingを選ぶことになります。
Amplify HostingのドキュメントはAmplify Gen2内には存在しないのですが Ampligy Gen2用のUIが用意されています。プレビュー版で、幾つか開発中の機能はあるものの、大幅に使いやすくなっていると感じました。
今回はGithubと連携し、Pushに合わせてリソースをデプロイするオーソドックスなデプロイを構築します。
デプロイ
Amplifyのホスティングのページに進むと、Amplify Gen2のSuggestが表示されています。
今回は、既にNextJSのソースコードがGitHubに配置されているものとします。
githubと連携し、リポジトリとブランチを指定します。
リポジトリをスキャンし、フレームワークが自動選択されることが分かります。
詳細設定からビルドイメージを選択できます。 執筆時点では、デフォルトの設定のままデプロイまで行うことが出来ており、特に設定を変えていません。
最後まで進めると、デプロイが完了しました。初回は10分ほど掛かりました。 ビルド・デプロイの項目をクリックすると、それぞれのプロセスの標準出力を確認し、異常がなかったかどうかを確認できます。
ここは従来のAmplify Hostingと同様、amplify.ymlで設定されたものが反映されます。 過去のデプロイの履歴の確認や、再デプロイも可能です。切り戻しに便利ですね。
Amplify Gen2のUIメニュー
これも従来のAmplify Hostingと同様ですが、環境変数やSecretを設定でき、ブランチ毎に値を出し分ける事ができます。 環境変数は、Amplify Hostingで管理し、CDK・フロントエンドで使用することができます。 Secretは、SSM Parameter Storeで管理し、Amplifyで作成したBackendサービスに適用できます。 記事には含めていませんが、Function(Lambda)を作成して、環境変数としてセキュアな値を受け取りたい時に便利でした。
リポジトリの設定は、ブランチの管理がポイントで、ブランチ名で判断し、GitHub上でのアクションが発生した時、自動でビルド処理を走らせるかどうかの調整ができます。
ビルドの設定では、amplify.ymlを編集し、ビルドとデプロイの設定を変更することができます。 また、ビルド時の通知や、incoming WebHookを飛ばし、例えばCodeCatalyst等の他アプリケーションと連携するような設定を行います。
カスタムドメインはまだ使えない
本来は、このメニューから、Route53や、独自に取得したドメインを簡単に設定できるのですが まだ利用できませんでした。ご注意下さい(見落としていて、痛い目を見ました・・・)
おまけ:デプロイ環境のローカルテスト
デプロイした環境をローカルで動作チェックしたい時、デプロイした環境とsandboxで作成した環境は別になります。 この環境を識別するファイルが、Amplify V6から用意された、amplifyconfiguration.jsonです(以前のaws-exports)。
generate configコマンドで、デプロイされたamplifyのスタックを選択することで、指定した環境のamplifyconfiguration.jsonを生成できるようになりました。以前の、Amplify env checkoutと似たような動きとして使えそうです。デプロイ時も、内部でこのコマンドが実行されているようです。
npx amplify generate config --stack hogehoge
ただ、執筆時点では、変更したCognitoのパスワードポリシーがconfigに反映されないといった不具合も確認されており プレビュー中ということもあり、正式版の発表が待たれる所ではあります。
その他、CLIを使用したリファレンスはこちらでまとめられています。
まとめ
Amplifyの基本的なアプリ作成とデプロイまでを紹介しました。 まだまだプレビュー版のAmplify Gen2ですが、ツールファーストからコードファーストに切り替わり、これまでのAmplifyの知識からのアップデートが必要と感じました。